<script setup lang="ts">
import { getLongTextToVoiceRes, getTextToVoiceRes, getLongTextToVoiceQueryRes } from '@/api/identify'
import axios from 'axios'
import { ref, defineProps, watch } from 'vue'
import useDownload from "@/hooks/useDownload";
const { downloadUrl, downloadFile } = useDownload()

const props = defineProps({
  text: {
    type: String
  }
})
const recognitionText = ref('111')
const textarea = ref('')
const playStatus = ref(1)
const playUrl = ref(null)
const downLoading = ref(false)
const audio = new Audio(null)

// 监听文本变化
watch(() => props.text, (val) => {
  audio.pause()
  playStatus.value = 1
  audio.src = null
  playUrl.value = ''
})

audio.onended = () => {
  playStatus.value = 1;
}

function arrayBufferToJson(arrayBuffer) {
  const uint8Array: any = new Uint8Array(arrayBuffer);
  const decodedString = String.fromCharCode.apply(null, uint8Array);
  return JSON.parse(decodedString);
}

const fetchTextToVoiceRes = async () => {
  const res: any = await getTextToVoiceRes([textarea.value]);
  return Promise.resolve(res)
}

const fetchLongTextToVoiceRes = async () => {
  return new Promise(async (resolve) => {
    const res: any = await getLongTextToVoiceRes([textarea.value])

    if (res.task_id) {
      let timer = setInterval(async () => {
        const data: any = await getLongTextToVoiceQueryRes([res.task_id])

        if (data.byteLength > 200) {
          clearInterval(timer)
          resolve(data)
          return
        }

        const json = arrayBufferToJson(data);
        if (json.tasks_info[0].task_status === 'Failure') {
          console.log('合成失败');
          clearInterval(timer)
          ElMessage.error('合成失败')
          resolve(null)
          return
        };

      }, 1000)
    } else {
      resolve(null)
    }
  })
}

const handleShortText = async (status: number) => {
  if (status === 1) {
    //直接播放
    if (playUrl.value) {
      playStatus.value = 3
      audio.src = playUrl.value
      audio.play()
      return
    }

    playStatus.value = 2
    const data: any = await fetchTextToVoiceRes()
    if (data) {
      playUrl.value = window.URL.createObjectURL(new Blob([data]))
      audio.src = playUrl.value
      audio.play()
    } else {
      ElMessage.error('合成失败')
    }
    playStatus.value = 3
  }


  if (status === 3) {
    playStatus.value = 1
    audio.pause()
  }
}

const handleLongText = async (status: number) => {
  if (status === 1) {
    //直接播放
    if (playUrl.value) {
      playStatus.value = 3
      audio.src = playUrl.value
      audio.play()
      return
    }

    playStatus.value = 2
    const data: any = await fetchLongTextToVoiceRes()
    if (data) {
      playUrl.value = window.URL.createObjectURL(new Blob([data]));
      audio.src = playUrl.value
      audio.play()
    } else {
      playStatus.value = 1
      return ElMessage.error('合成失败')
    }

    playStatus.value = 3
  }


  if (status === 3) {
    playStatus.value = 1
    audio.pause()
  }
}

const download = async () => {
  if (!textarea.value) {
    return ElMessage.warning('请填写内容')
  }
  
  if (playUrl.value) {
    downloadUrl.value = playUrl.value;
    downloadFile(downloadUrl.value, '文本合成.mp3');
    return
  }
  
  downLoading.value = true
  if (props.text === '短文本合成') {
    const data: any = await fetchTextToVoiceRes()
    if (data) {
      playUrl.value = window.URL.createObjectURL(new Blob([data]))
      downLoading.value = false
    }
    else {
      downLoading.value = false
      return ElMessage.error('合成失败')
    }
    downLoading.value = false
  }
  if (props.text === '长文本合成') {
    const data: any = await fetchLongTextToVoiceRes()
    if (data) {
      // 跨域了
      playUrl.value = window.URL.createObjectURL(new Blob([data]))
      downLoading.value = false
    }
    else {
      downLoading.value = false
      return ElMessage.error('合成失败')
    }
    downLoading.value = false
  }

  downloadUrl.value = playUrl.value;
  downloadFile(downloadUrl.value, '文本合成.mp3');
}
const clearImg = () => {
  textarea.value = ''
  playStatus.value = 1
  audio.src = null
  playUrl.value = ''
}
const play = (status: number) => {

  if (!textarea.value.length) {
    ElMessage.warning('请输入你要转换的内容')
    return
  }

  if (props.text === '短文本合成') {
    handleShortText(status)
  }
  if (props.text === '长文本合成') {
    handleLongText(status)
  }
}

</script>

<template>
  <div class="putVoiceBox audio-trans">
    <div class="putVoice">
      <div class="preview">
        <div>文字转语音</div>
        <div class="addmore" style="margin-left: 20px" @click="clearImg">
          <el-icon class="iconClear">
            <Delete />
          </el-icon>
          <div>清空</div>
        </div>
      </div>
      <div class="getImg" :class="{ 'text-preview': recognitionText }">
        <el-input v-model="textarea" type="textarea" placeholder="Please input" resize="none"
          :autosize="{ minRows: 10 }" />
      </div>
      <div class="footerBtn">
        <div class="addmore" @click="play(1)" v-if="playStatus == 1">
          <el-icon class="iconClear">
            <VideoPlay />
          </el-icon>
          <div>试听一下</div>
        </div>
        <div class="addmore" v-else-if="playStatus == 2">
          <el-icon class="iconClear is-loading">
            <Loading />
          </el-icon>
          <div>正在合成</div>
        </div>
        <div class="addmore" @click="play(3)" v-else-if="playStatus == 3">
          <el-icon class="iconClear">
            <VideoPause />
          </el-icon>
          <div>正在播放</div>
        </div>

        <div class="addmore" v-if="downLoading">
          <el-icon class="iconClear is-loading">
            <Loading />
          </el-icon>
          <div>正在下载</div>
        </div>
        <div class="addmore" @click="download" v-else>
          <el-icon class="iconClear">
            <Download />
          </el-icon>
          <div>立即下载</div>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
  .audio-trans {
    width: 65%;
    display: flex;
    align-items: center;
    padding-top: 30px;

    .getImg {
      :deep(.el-textarea__inner) {
        box-shadow: unset;
      }

      :deep(.el-textarea__inner:hover) {
        box-shadow: unset;
      }
    }

    .input-box {
      width: 400px;

      .center {
        :deep(.el-form-item__content) {
          justify-content: center;
        }
      }
    }

    .putVoiceBox {
      flex: 1;
      padding-left: 60px;
    }
  }

  .main {
    min-height: 1500px;
    // padding: 20px;
    background-color: var(--main-shallowbg-color);
  }

  // .putBox {
  //   // width: 90%;
  //   // margin: 50px auto;
  //   // display: flex;
  //   // justify-content: space-around;
  // }
  .inputVoice {
    opacity: 0.0;
    width: 100%;
    height: 100%;
    top: 0px;
    left: 0px;
    position: absolute;
  }

  // .putVoice:hover {
  //   box-shadow: 9px 8px 12px var(--main-shallowfont-color);
  // }
  .putVoiceBox {
    width: 90%;
    height: 420px;
    /* margin: 10px auto; */

    .text-preview {
      overflow-y: auto;
      display: block;
      box-sizing: border-box;
      padding-left: 10px;
      padding-top: 10px;
      padding-bottom: 10px;

      p {
        margin: 0;
        line-height: 1.5;
      }
    }
  }

  .putVoice {
    position: relative;
    transition-property: all;
    transition-duration: 0.6s;
    width: 100%;
    height: 400px;
    background-color: var(--main-bg-color);
    color: var(--main-font-color);
    // display: flex;
    // flex-direction: column;
    // justify-content: center;
    // align-items: center;
    border-radius: 10px;
  }

  .preview {
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 10%;
    width: 90%;
    margin: 0px auto;
    font-size: 15px;
  }

  .getImg {
    position: relative;
    transition-property: all;
    transition-duration: 0.6s;
    width: 90%;
    height: 75%;
    margin: 5px auto 0px;
    background-color: var(--main-bg-color);
    color: var(--main-font-color);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    border-radius: 10px;
    border: 4px dotted var(--main-shallowbg-color);

    img {
      width: 100%;
      height: 100%;
    }

    .icon {
      font-size: 60px;
      margin-top: -60px;
      margin-bottom: 20px;
      position: relative;
      top: 0px;
      animation-name: example;
      animation-duration: 1s;
      animation-iteration-count: infinite;
      animation-direction: alternate;
      animation-timing-function: linear;
    }

    .h3 {
      font-size: 25px;
      font-weight: 600;
      margin-bottom: 10px;
    }

    .h5 {
      color: #969696;
    }
  }

  @keyframes example {
    from {
      top: 0;
    }

    to {
      top: 12px;
    }
  }

  .addmore {
    transition-property: all;
    transition-duration: 0.5s;
    width: 25%;
    height: 27px;
    border-radius: 10px;
    border: 1px solid;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    cursor: pointer;

    .iconClear {
      font-size: 15px;
    }
  }

  .addmore:hover {
    box-shadow: 3px 3px 4px 1px var(--main-shallowfont-color);
  }

  .footerBtn {
    width: 90%;
    height: 10%;
    margin: 10px auto;
    display: flex;
    justify-content: flex-end;
    font-size: 15px;
  }

  .languageBox {
    background-color: var(--main-shallowbg-color);
    // width: 60%;
    // height: 400px;
    padding: 10px;
    color: var(--main-font-color);
  }

  .radioBox {
    margin-top: 10px;
  }

  ::v-deep .el-radio-group {
    margin: 10px;
  }

  ::v-deep .el-radio-button__inner {
    color: var(--main-font-color);
    background-color: var(--main-bg-color);
  }

  ::v-deep .el-radio-button__original-radio:checked+.el-radio-button__inner {
    color: var(--main-bg-color);
    background-color: var(--main-font-color);
    border: var(--main-font-color);
    box-shadow: none;
  }

  @media screen and (min-width: 600px) {
    .main {
      min-height: 1500px;
      // padding: 20px;
      background-color: var(--main-shallowbg-color);
    }

    .putBox {
      width: 95%;
      margin: 0px auto;
      display: flex;
      justify-content: space-around;
    }

    .inputVoice {
      opacity: 0.0;
      width: 100%;
      height: 100%;
      top: 0px;
      left: 0px;
      position: absolute;
    }

    // .putVoice:hover {
    //   box-shadow: 9px 8px 12px var(--main-shallowfont-color);
    // }
    .putVoiceBox {
      width: 40%;
      // height: 400px;
      margin: 10px;
    }

    .putVoice {
      position: relative;
      transition-property: all;
      transition-duration: 0.6s;
      width: 100%;
      height: 470px;
      background-color: var(--main-bg-color);
      color: var(--main-font-color);
      // display: flex;
      // flex-direction: column;
      // justify-content: center;
      // align-items: center;
      border-radius: 10px;
    }

    .preview {
      display: flex;
      justify-content: space-between;
      align-items: center;
      height: 10%;
      width: 90%;
      margin: 0px auto;
      font-size: 17px;
    }

    .getImg {
      position: relative;
      transition-property: all;
      transition-duration: 0.6s;
      width: 90%;
      height: 80%;
      margin: 0px auto;
      background-color: var(--main-bg-color);
      color: var(--main-font-color);
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      border-radius: 10px;
      border: 4px dotted var(--main-shallowbg-color);

      img {
        width: 100%;
        height: 100%;
      }

      .icon {
        font-size: 60px;
        margin-top: -60px;
        margin-bottom: 20px;
      }

      .h3 {
        font-size: 25px;
        font-weight: 600;
        margin-bottom: 10px;
      }

      .h5 {
        color: #969696;
      }
    }

    .languageBox {
      background-color: var(--main-shallowbg-color);
      width: 90%;
      margin: 0px auto;
      // height: 400px;
      // padding: 30px 40px 30px 30px;
      color: var(--main-font-color);
    }

    .radioBox {
      margin: 10px;
    }

    .addmore {
      width: 18%;
      // height: 35px;
      padding: 1px 10px;
      border-radius: 10px;
      border: 1px solid;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
      margin-left: 20px;

      .iconClear {
        font-size: 20px;
      }
    }

    .footerBtn {
      width: 90%;
      height: 10%;
      margin: 10px auto;
      display: flex;
      justify-content: flex-end;
    }
  }
</style>